home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK2.toast / Development Kits (Disc 2) / QuickTime / Programming Stuff / Sample Code / Music Architecture / Mixed Bag / •QTMusic Sample Keyboards / QTMusic Sample Keyboards.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-09  |  7.7 KB  |  422 lines  |  [TEXT/KAHL]

  1. /*
  2.  *    File:        QTMusic Sample Keyboards.c
  3.  */
  4.  
  5.  
  6. /*--------------------------
  7.     Inclusions
  8. --------------------------*/
  9.  
  10. #include <QuickDraw.h>
  11. #include <Memory.h>
  12. #include <Windows.h>
  13. #include <Controls.h>
  14.  
  15. #include <QuickTimeComponents.h>
  16. #include <BDC.h>
  17.  
  18. #include "EasyKeyboardDiagram.h"
  19.  
  20. #include "BigEasy2.h"
  21. #include "BigEasyUtils.h"
  22. #include "BigEasyGrafish.h"
  23.  
  24. /*--------------------------
  25.     Limits and Konstants
  26. --------------------------*/
  27. enum
  28.     {
  29.     mFirstDocOnly = 100,
  30.     mClose,
  31.     mLastDocOnly,
  32.     mOpen
  33.     };
  34.  
  35. typedef struct
  36.     {
  37.     KeyboardDiagram kd;
  38.     NoteRequest nr;
  39.     NoteChannel nc;
  40.  
  41.     short panelTop;
  42.     ControlHandle instrumentButton;
  43.     Rect statR;
  44.     } QTMPanel;
  45.  
  46. #define kPanelCount 3
  47.  
  48. typedef struct
  49.     {
  50.     WindowPtr w;
  51.  
  52.     NoteAllocator na;
  53.  
  54.     QTMPanel panel[kPanelCount];
  55.     } Globals;
  56.  
  57. Globals *g = nil;
  58.  
  59. /*--------------------------
  60.     Formatting
  61. --------------------------*/
  62.  
  63.  
  64. #define kOctaveCount 5
  65. #define kHeaderHeight 17
  66. #define kDocMargin 8
  67. #define kKeyboardWidth (kOctaveCount * kKeyboardOctaveWidth + 1)
  68. #define kInstrumentButtonHeight 20
  69. #define kInstrumentButtonWidth 120
  70. #define kStatHeight 32
  71. #define kTextAllowance 13
  72. #define kStatWidth 160
  73.  
  74. #define kPanelHeight (3*kDocMargin + kKeyboardHeight + kStatHeight)
  75.  
  76.  
  77.  
  78. #define kPanelTop(x) (x * kPanelHeight)
  79.  
  80. #define kKeyboardLeft kDocMargin
  81. #define kKeyboardRight (kKeyboardLeft + kKeyboardWidth)
  82. #define kKeyboardTop(x) (kPanelTop(x)+2*kDocMargin+kStatHeight)
  83.  
  84. #define kStatLeft kDocMargin
  85. #define kStatRight (kStatLeft + kStatWidth)
  86. #define kStatTop(x) (kPanelTop(x)+kDocMargin)
  87.  
  88. #define kInstrumentButtonLeft (kStatRight + kDocMargin)
  89. #define kInstrumentButtonRight (kInstrumentButtonLeft + kInstrumentButtonWidth)
  90. #define kInstrumentButtonTop(x) (kStatTop(x) + (kStatHeight-kInstrumentButtonHeight))
  91.  
  92. #define kWindowWidth (kKeyboardWidth+2*kDocMargin)
  93. #define kWindowHeight (kPanelCount * kPanelHeight)
  94.  
  95.  
  96.  
  97. /*--------------------------
  98.     Prototypes
  99. --------------------------*/
  100. static void DrawDoc(short n);
  101. static void ClickDoc(short n,Point p,short mods);
  102. static void KeyDoc(short n,short key,short code,short mods);
  103. static void IdleDoc(short n, Boolean front);
  104. static void ActivateDoc(short n);
  105. static void DeactivateDoc(short n);
  106. static void LetsQuit(short n,short menuItem,short menuRef);
  107. static void OpenWindow();
  108. static void InitVars(void);
  109.  
  110. static void TrackKeyboardClick(KeyboardDiagram *kd,NoteAllocator na,NoteChannel nc,Point p);
  111. static void DrawNum(long n);
  112.  
  113. static void DrawStat(short i);
  114. /*--------------------------
  115.     Computer Programs
  116. --------------------------*/
  117.  
  118.  
  119. void DrawDoc(short n)
  120. /*
  121.  * Draws the window.
  122.  */
  123.     {
  124.     Rect r;
  125.     QTMPanel *p;
  126.     short i;
  127.  
  128.     GoBW();
  129.  
  130.  
  131.     RGBFore(50000,50000,65535);
  132.     r = qd.thePort->portRect;
  133.     PaintRect(&r);
  134.     GoBW();
  135.  
  136.     DrawControls(g->w);
  137.  
  138.     for(i = 0; i < kPanelCount; i++)
  139.         {
  140.         DrawStat(i);
  141.  
  142.         p = &g->panel[i];
  143.         DrawKeyboard(&p->kd);
  144.  
  145.         if(i)
  146.             {
  147.             MoveTo(0,p->panelTop);
  148.             Line(kWindowWidth,0);
  149.             }
  150.         }
  151.     }
  152.  
  153. void DrawStat(short i)
  154.     {
  155.     Rect r;
  156.     QTMPanel *panel;
  157.     Str31 s;
  158.  
  159.     GoBW();
  160.  
  161.     TextSize(9);
  162.     panel = &g->panel[i];
  163.  
  164.     r = panel->statR;
  165.  
  166.     FrameRect(&r);
  167.     MoveTo(r.left + 3,r.bottom);
  168.     LineTo(r.right,r.bottom);
  169.     LineTo(r.right,r.top + 3);
  170.     InsetRect(&r,1,1);
  171.     EraseRect(&r);
  172.  
  173.     MoveTo(r.left + 3,r.top + kTextAllowance);
  174.     DrawString(panel->nr.tone.synthesizerName);
  175.     if(panel->nr.tone.synthesizerType)
  176.         {
  177.         DrawString("\p (");
  178.         s[0] = 4;
  179.         s[1] = panel->nr.tone.synthesizerType >> 24;
  180.         s[2] = panel->nr.tone.synthesizerType >> 16;
  181.         s[3] = panel->nr.tone.synthesizerType >> 8;
  182.         s[4] = panel->nr.tone.synthesizerType;
  183.         DrawString(s);
  184.         DrawString("\p)");
  185.         }
  186.  
  187.     MoveTo(r.left + 3,r.top + 2*kTextAllowance);
  188.     DrawString(panel->nr.tone.instrumentName);
  189.     DrawString("\p (");
  190.     DrawNum(panel->nr.tone.instrumentNumber);
  191.     DrawString("\p / ");
  192.     DrawNum(panel->nr.tone.gmNumber);
  193.     DrawString("\p)");
  194.     }
  195.  
  196. void DrawNum(long n)
  197. /*
  198.   * Draw number n as a signed long, in decimal
  199.   */
  200.     {
  201.     Str31 c;
  202.  
  203.     NumToString(n,c);
  204.     DrawString(c);
  205.     }
  206.  
  207.  
  208.  
  209. void ClickDoc(short n,Point p,short mods)
  210. /*
  211.  * Come here for a click in the window.
  212.  */
  213.     {
  214.     QTMPanel *panel;
  215.     short i;
  216.     ControlHandle cH;
  217.     short part;
  218.  
  219.     part = FindControl(p,g->w,&cH);
  220.     if(cH)
  221.         {
  222.         part = TrackControl(cH,p,nil);
  223.         if(part)
  224.             {
  225.             ComponentResult result;
  226.  
  227.             i = GetControlReference(cH);
  228.             panel = &g->panel[i];
  229.  
  230.             result = NAPickInstrument(g->na, nil, "\pNew Instrument:", &panel->nr.tone,
  231.                     0, 0, nil, nil);
  232.  
  233.             if(!result)
  234.                 {
  235.                 NADisposeNoteChannel(g->na,panel->nc);
  236.                 panel->nc = 0;
  237.                 NANewNoteChannel(g->na,&panel->nr,&panel->nc);
  238.                 DrawStat(i);
  239.                 }
  240.             }
  241.  
  242.  
  243.         goto doneClick;
  244.         }
  245.  
  246.  
  247.     for(i = 0; i < kPanelCount; i++)
  248.         {
  249.         panel = &g->panel[i];
  250.         if(PtInRect(p,&panel->kd.r))        /* clicked in keyboard picture? */
  251.             {
  252.             TrackKeyboardClick(&panel->kd,g->na,panel->nc,p);    /* play musical notes */
  253.  
  254.             goto doneClick;
  255.             }
  256.         }
  257.  
  258. doneClick:;
  259.     }
  260.  
  261.  
  262. void TrackKeyboardClick(KeyboardDiagram *kd,NoteAllocator na,NoteChannel nc,Point p)
  263.     {
  264.     short pitch,lastPitch;
  265.     long velocity;
  266.     short mods;
  267.  
  268.     lastPitch = 0;
  269.     do
  270.         {
  271.         pitch = GetKeyboardKey(kd,p);
  272.         if(pitch < 0)
  273.             pitch = 0;
  274.         GetMouse(&p);
  275.         if(pitch != lastPitch)
  276.             {
  277.             NAPlayNote(na,nc,lastPitch,0);
  278.             if(pitch >= 0)
  279.                 {
  280.                 mods = GetModKeys();
  281.                 velocity = 64 + (mods & optionKey ? 20 : 0) + (mods & cmdKey ? 32 : 0);
  282.  
  283.                 NAPlayNote(na,nc,pitch,velocity);
  284.                 }
  285.  
  286.             PaintKeyboardKey(kd,lastPitch,0);
  287.             PaintKeyboardKey(kd,pitch,255);
  288.             lastPitch = pitch;
  289.             }
  290.         } while(StillDown());
  291.  
  292.     PaintKeyboardKey(kd,lastPitch,0);
  293.     NAPlayNote(na,nc,lastPitch,0);
  294.     }
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301. void KeyDoc(short n,short key,short code,short mods)
  302.     {
  303.     #pragma unused (n,key,code,mods)
  304.     }
  305.  
  306. void IdleDoc(short n, Boolean front)
  307.     {
  308.     #pragma unused (n,front)
  309.     }
  310.  
  311.  
  312. void ActivateDoc(short n)
  313.     {
  314.     #pragma unused (n)
  315.  
  316.     SetMenuItemRange(mFirstDocOnly,mLastDocOnly,1,0);
  317.     SetMenuItem(mOpen,-1,0,0,nil);                /* disable "Open" menu item        */
  318.     }
  319.  
  320. void DeactivateDoc(short n)
  321.     {
  322.     #pragma unused (n)
  323.  
  324.     SetMenuItemRange(mFirstDocOnly,mLastDocOnly,-1,0);
  325.     SetMenuItem(mOpen,1,0,0,nil);                /* enable "Open" menu item        */
  326.     }
  327.  
  328. void LetsQuit(short n,short menuItem,short menuRef)
  329.     {
  330.     #pragma unused (n,menuItem,menuRef)
  331.     gQuitApp++;
  332.     }
  333.  
  334. void OpenWindow(void)
  335.     {
  336.     Rect r;
  337.  
  338.     SetRect(&r,0,0,kWindowWidth,kWindowHeight);
  339.     OffsetRect(&r,30,50);
  340.  
  341.     g->w = InstallWindow(1,(StringPtr)0x910,&r,0,wCopyDraw + wPrintDraw,
  342.             DrawDoc,ClickDoc,KeyDoc,nil,
  343.             ActivateDoc,DeactivateDoc,IdleDoc);
  344.     }
  345.  
  346. void InitVars()
  347. /*
  348.  * Called once at startup: yes, it
  349.  * inits the vars.
  350.  */
  351.     {
  352.     short i;
  353.     Rect r;
  354.     QTMPanel *p;
  355.  
  356.     g = (Globals *)NewPtrClear(sizeof(Globals));
  357.  
  358.     OpenWindow();
  359.  
  360.     g->na = OpenDefaultComponent('nota',0);
  361.  
  362.     for(i = 0; i < kPanelCount; i++)
  363.     /*
  364.      * For each leetle keyboard picture, startup
  365.      * the keyboard diagram, and allocate a "NoteChannel"
  366.      * upon which we shall play musical notes.
  367.      *
  368.      * Start each keyboard with the sound of General MIDI instrument 1.
  369.      */
  370.         {
  371.         p = &g->panel[i];
  372.  
  373.         r.left = kKeyboardLeft;
  374.         r.right = kKeyboardRight;
  375.         r.top = kKeyboardTop(i);
  376.         r.bottom = r.top + kKeyboardHeight;
  377.         InitializeKeyboard(&p->kd,&r,kOctaveCount,36);
  378.  
  379.         r.left = kInstrumentButtonLeft;
  380.         r.right = kInstrumentButtonRight;
  381.         r.top = kInstrumentButtonTop(i);
  382.         r.bottom = r.top + kInstrumentButtonHeight;
  383.  
  384.         p->instrumentButton = NewControl(g->w, &r,"\pInstrument…", true, 0,0,1,
  385.                 pushButProc, i);
  386.  
  387.         p->panelTop = kPanelTop(i);
  388.  
  389.         p->statR.left = kStatLeft;
  390.         p->statR.right = kStatRight;
  391.         p->statR.top = kStatTop(i);
  392.         p->statR.bottom = p->statR.top + kStatHeight;
  393.  
  394.         p->nr.polyphony = 2;
  395.         p->nr.typicalPolyphony = 0x00010000;
  396.         NAStuffToneDescription(g->na,1,&p->nr.tone);
  397.         NANewNoteChannel(g->na,&p->nr,&p->nc);
  398.         }
  399.     }
  400.  
  401. void Bootstrap()
  402.     {
  403.     InitVars();
  404.  
  405. /*** File Menu ***/
  406.     InstallMenu("\pFile",nil,0);
  407.     InstallPrintItems(nil,nil);
  408.     InstallMenuItem("\p(-",nil,0);
  409.     InstallQuitItem(LetsQuit,0);
  410.  
  411. /*** Edit Menu ***/
  412.     InstallEditMenu(nil,nil,nil,nil,nil);
  413.  
  414.     }
  415.  
  416. void Hatstrap()
  417. /*
  418.   * clean up
  419.   */
  420.     {
  421.     }
  422.